package com.rose.doorto.footbathdoor.web;


import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayConstants;
import com.alipay.api.internal.util.AlipaySignature;
import com.rose.doorto.footbathdoor.service.PaymentInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import com.rose.doorto.common.exception.BizCodeEnum;
import com.rose.doorto.common.exception.BizException;
import com.rose.doorto.footbathdoor.config.AlipayTemplate;
import com.rose.doorto.footbathdoor.enums.OrderStatusEnum;
import com.rose.doorto.footbathdoor.enums.PayType;
import com.rose.doorto.footbathdoor.pojo.Order;
import com.rose.doorto.footbathdoor.service.OrderService;
import com.rose.doorto.footbathdoor.vo.AlipayVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Map;

/**
 * @Author 李庆超
 * @email 1481791489@qq.com
 * @Package：com.rose.doorto.footbathdoor.controler
 * @Project：door-to-door
 * @name：AliPayController
 * @date 2024/08/09 2024/8/9:14:19:
 */
@Slf4j
@Controller
//@RequestMapping("/alipay")
public class AliPayController {


    @Resource
    AlipayTemplate alipayTemplate;

    @Resource
    OrderService orderService;

    @Resource
    private Environment config;

    @Autowired
    private PaymentInfoService paymentInfoService;


    public String alipayPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkjwK/ULT3DiHCr314eZp2v7LfVixsu76fYab/vfPFBMaxVSTUzub7H2M4crtWUOPgkHdm9kT7VxeLeCmzKPuUaohnVCmfx1+Xhn419sVa7CYga7W42t5nahTLIgltJNm0JMFCKUMrlQwURjRTBXm9QMpnxD1nzyUNgoe0vTF+cidNnTmCqc+gu/oATDwOsMjfSBEzWt7G3JMM8fKKV0vnJLe3LSSQ/6PAaQyazgktWCJNXNbIgTbW8IoWGCD9e/p0lvBKjLCYSm0417YtsjCT7rcGoNEI5UV9vT5NFhWyhpZFwXTHm6hCy9HNqXwjseRzxLSt9EOB0XYeVag64ylfQIDAQAB";
    /**
     * 支付成功后跳转到订单列表页
     * @param orderSn
     * @return
     * @throws AlipayApiException
     */
    @GetMapping(value = "/alipay/payOrder", produces = "text/html;charset=UTF-8")
    @ResponseBody
    public String payOrder(@RequestParam("orderSn") String orderSn) throws AlipayApiException {
        Order order = orderService.getOrderByOrderSn(orderSn);
        if (order == null){
            return "该订单不存在";
        }else if (order.getStatus()!= OrderStatusEnum.CREATE_NEW.getCode()){
            return "该订单不是待付款状态";
        }
        AlipayVO alipayVO = new AlipayVO();
        //订单号
        alipayVO.setOutTradeNo(orderSn);
        //支付宝支付要求金额必须为小数点后两位
        alipayVO.setTotalAmount(order.getRewardPrice().setScale(2, BigDecimal.ROUND_UP).toString());
        alipayVO.setSubject("广庆到家订单");
        alipayVO.setBody("广庆到家订单");
        try {
            String response = alipayTemplate.pay(alipayVO);
            //TODO 支付方式,需要记录入库,有问题,后期改
            orderService.updateOrderPayType(order.getOrderSn(),PayType.ALIPAY.getCode());
            log.info("支付宝支付响应: {}",response);
            return response;
        }catch (AlipayApiException e){
            log.error("阿里支付失败：{}", e.getMessage());
            throw new BizException(BizCodeEnum.ORDER_PAY_FEILED);
        }
    }

    /**
     * 这个方法的返回值一定要是success，因为支付宝只有接收到success才会认为应用已经接收到了支付成功的通知，
     * 否则支付宝会不停地向应用发送通知，以下便是支付宝提供给我们的所有参数：
     * @param params
     * @return
     */
    @ResponseBody
    @PostMapping("alipay/notify")//(value = "alipay/notify",headers = "Content-Type = application/x-www-form-urlencoded")  // 注意这里必须是POST接口
    public String payNotify(@RequestParam Map<String, String> params) {
        log.info("支付通知正在执行");
        log.info("通知参数 ===> {}", params);
        String result = "failure";

        try {
            //异步通知验签
            boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayPublicKey, AlipayConstants.CHARSET_UTF8,AlipayConstants.SIGN_TYPE_RSA2);
            if(!signVerified){
                //验签失败则记录异常日志，并在response中返回failure.
                log.error("支付成功异步通知验签失败！");
                return result;
            }

            // 验签成功后
            log.info("支付成功异步通知验签成功！");

            //按照支付结果异步通知中的描述，对支付结果中的业务内容进行二次校验，
            //1 商户需要验证该通知数据中的 out_trade_no 是否为商户系统中创建的订单号
            String outTradeNo = params.get("out_trade_no");
            Order order = orderService.getOrderByOrderSn(outTradeNo);
//            OrderInfo order = orderInfoService.getOrderByOrderNo(outTradeNo);
            if(order == null){
                log.error("订单不存在");
                return result;
            }

            //2 判断 total_amount 是否确实为该订单的实际金额（即商户订单创建时的金额）
            String totalAmount = params.get("total_amount");
            BigDecimal totalFeeInt = order.getRewardPrice();
            BigDecimal decimal = new BigDecimal(totalAmount);
            if(!decimal.equals(totalFeeInt)){
                log.error("金额校验失败");
                return result;
            }
//            //3 校验通知中的 seller_id（或者 seller_email) 是否为 out_trade_no 这笔单据的对应的操作方
//            String sellerId = params.get("seller_id");
//            System.out.println("sellerId是===="+sellerId);
//            String sellerIdProperty = config.getProperty("alipay.seller-id");
//            System.out.println("sellerIdProperty是===="+sellerIdProperty);
//            if(!sellerId.equals(sellerIdProperty)){
//                log.error("商家pid校验失败");
//                return result;
//            }
            //4 验证 app_id 是否为该商户本身
            String appId = params.get("app_id");
            String appIdProperty = config.getProperty("alipay.app-id");
            if(!appId.equals(appIdProperty)){
                log.error("appid校验失败");
                return result;
            }
            //在支付宝的业务通知中，只有交易通知状态为 TRADE_SUCCESS时，
            // 支付宝才会认定为买家付款成功。
            String tradeStatus = params.get("trade_status");
            if(!"TRADE_SUCCESS".equals(tradeStatus)){
                log.error("支付未成功");
                return result;
            }
            //处理业务 修改订单状态 记录支付日志
            paymentInfoService.createPaymentInfoForAliPay(params);
            orderService.updateOrderPayType(outTradeNo,OrderStatusEnum.SENDED.getCode());
            //校验成功后在response中返回success并继续商户自身业务处理，校验失败返回failure
            result = "success";
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return result;
    }

}
